﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bmz.Laboratory.DesignPattern
{
    /// <summary>
    /// 抽象工厂
    /// </summary>
    class AbstractFactory
    {
        #region 人

        /// <summary>
        /// 人种接口
        /// </summary>
        public interface Human
        {

            //每个人种都有相应的颜色
            void getColor();

            //人类会说话
            void talk();

            //每个人都有性别
            void getSex();

        }
        /// <summary>
        /// 白色人种
        /// </summary>
        public abstract class AbstractWhiteHuman : Human
        {

            //白色人种的颜色是白色的
            public void getColor()
            {
                Console.WriteLine("白色人种的皮肤颜色是白色的！");
            }

            //白色人种讲话
            public void talk()
            {
                Console.WriteLine("白色人种会说话，一般都是但是单字节。");
            }

            public abstract void getSex();
        }

        /// <summary>
        /// 黑色人种
        /// </summary>
        public abstract class AbstractBlackHuman : Human
        {
            public void getColor()
            {
                Console.WriteLine("黑色人种的皮肤颜色是黑色的！");
            }

            public void talk()
            {
                Console.WriteLine("黑人会说话，一般人听不懂。");
            }

            public abstract void getSex();
        }

        /// <summary>
        /// 黄色人种
        /// </summary>
        public abstract class AbstractYellowHuman : Human
        {
            public void getColor()
            {
                Console.WriteLine("黄色人种的皮肤颜色是黄色的！");
            }

            public void talk()
            {
                Console.WriteLine("黄色人种会说话，一般说的都是双字节。");
            }

            public abstract void getSex();
        }

        /// <summary>
        /// 黄色女性人种
        /// </summary>
        public class FemaleYellowHuman : AbstractYellowHuman
        {

            //黄人女性
            public override void getSex()
            {
                Console.WriteLine("黄人女性");
            }

        }

        /// <summary>
        /// 黄色男性人种
        /// </summary>
        public class MaleYellowHuman : AbstractYellowHuman
        {
            //黄人男性
            public override void getSex()
            {
                Console.WriteLine("黄人男性");
            }
        }

        /// <summary>
        /// 黑色女性人种
        /// </summary>
        public class FemaleBlackHuman : AbstractBlackHuman
        {

            //黑人女性
            public override void getSex()
            {
                Console.WriteLine("黑人女性");
            }
        }

        /// <summary>
        /// 黑色男性人种
        /// </summary>
        public class MaleBlackHuman : AbstractBlackHuman
        {
            //黑人男性
            public override void getSex()
            {
                Console.WriteLine("黑人男性");
            }
        }

        /// <summary>
        /// 白色女性人种
        /// </summary>
        public class FemaleWhiteHuman : AbstractWhiteHuman
        {

            //白人女性
            public override void getSex()
            {
                Console.WriteLine("白人女性");
            }
        }

        /// <summary>
        /// 白色男性人种
        /// </summary>
        public class MaleWhiteHuman : AbstractWhiteHuman
        {
            //白人男性
            public override void getSex()
            {
                Console.WriteLine("白人男性");
            }
        }

        /// <summary>
        /// 八卦炉定义
        /// </summary>
        public interface HumanFactory
        {
            //制造一个黄色人种
            Human createYellowHuman();

            //制造一个白色人种
            Human createWhiteHuman();

            //制造一个黑色人种
            Human createBlackHuman();
        }

        /// <summary>
        /// 生产女性八卦炉
        /// </summary>
        public class FemaleFactory : HumanFactory
        {
            //生产出黑人女性
            public Human createBlackHuman()
            {
                return new FemaleBlackHuman();
            }

            //生产出白人女性
            public Human createWhiteHuman()
            {
                return new FemaleWhiteHuman();
            }

            //生产出黄人女性
            public Human createYellowHuman()
            {
                return new FemaleYellowHuman();
            }
        }

        /// <summary>
        /// 生产男性八卦炉
        /// </summary>
        public class MaleFactory : HumanFactory
        {
            //生产出黑人男性
            public Human createBlackHuman()
            {
                return new MaleBlackHuman();
            }

            //生产出白人男性
            public Human createWhiteHuman()
            {
                return new MaleWhiteHuman();
            }

            //生产出黄人男性
            public Human createYellowHuman()
            {
                return new MaleYellowHuman();
            }

        }

        public class NvWa
        {
            public static void main(String[] args)
            {
                //第一条生产线，男性生产线
                HumanFactory maleHumanFactory = new MaleFactory();
                //第二条生产线，女性生产线
                HumanFactory femaleHumanFactory = new FemaleFactory();
                //生产线建立完毕，开始生产人了:
                Human maleYellowHuman = maleHumanFactory.createYellowHuman();
                Human femaleYellowHuman = femaleHumanFactory.createYellowHuman();
                Console.WriteLine("---生产一个黄色女性---");
                femaleYellowHuman.getColor();
                femaleYellowHuman.talk();
                femaleYellowHuman.getSex();
                Console.WriteLine("\n---生产一个黄色男性---");
                maleYellowHuman.getColor();
                maleYellowHuman.talk();
                maleYellowHuman.getSex();
                /*
                * .....
                * 后面继续创建
                */
            }
        }
        #endregion

        #region 产品

        public abstract class AbstractProductA
        {
            //每个产品共有的方法
            public void shareMethod()
            {
            }

            //每个产品相同方法，不同实现
            public abstract void doSomething();

        }

        public class ProductA1 : AbstractProductA
        {
            public override void doSomething()
            {
                Console.WriteLine("产品A1的实现方法");
            }
        }

        public class ProductA2 : AbstractProductA
        {
            public override void doSomething()
            {
                Console.WriteLine("产品A2的实现方法");
            }
        }

        public abstract class AbstractProductB
        {
            //每个产品共有的方法
            public void shareMethod()
            {
            }

            //每个产品相同方法，不同实现
            public abstract void doSomething();

        }

        public class ProductB1 : AbstractProductB
        {
            public override void doSomething()
            {
                Console.WriteLine("产品B1的实现方法");
            }
        }

        public class ProductB2 : AbstractProductB
        {
            public override void doSomething()
            {
                Console.WriteLine("产品B2的实现方法");
            }
        }

        public abstract class AbstractCreator
        {
            //创建A产品家族
            public abstract AbstractProductA createProductA();

            //创建B产品家族
            public abstract AbstractProductB createProductB();
        }

        public class Creator1 : AbstractCreator
        {

            //只生产产品等级为1的A产品
            public override AbstractProductA createProductA()
            {
                return new ProductA1();
            }

            //只生产产品等级为1的B产品
            public override AbstractProductB createProductB()
            {
                return new ProductB1();
            }

        }

        public class Creator2 : AbstractCreator
        {

            //只生产产品等级为2的A产品
            public override AbstractProductA createProductA()
            {
                return new ProductA2();
            }

            //只生产产品等级为2的B产品
            public override AbstractProductB createProductB()
            {
                return new ProductB2();
            }

        }

        public class Client
        {
            public static void main(String[] args)
            {
                //定义出两个工厂
                AbstractCreator creator1 = new Creator1();
                AbstractCreator creator2 = new Creator2();
                //产生A1对象
                AbstractProductA a1 = creator1.createProductA();
                a1.doSomething();
                //产生A2对象
                AbstractProductA a2 = creator2.createProductA();
                a2.doSomething();
                //产生B1对象
                AbstractProductB b1 = creator1.createProductB();
                b1.doSomething();
                //产生B2对象
                AbstractProductB b2 = creator2.createProductB();
                b2.doSomething();
                /*
                * 然后在这里就可以为所欲为了...
                */
            }
        }
        #endregion
    }
}
